package helper.base.math

import helper.base.list.ArrayListHelper.ArrayExpand.toDoubleList
import helper.base.list.DoubleListList
import helper.base.math.DoubleMatrixHelper.DoubleMatrix
import helper.base.math.DoubleMatrixHelper.DoubleMatrix.Companion.makeDoubleMatrix
import helper.base.math.DoubleMatrixHelper.DoubleMatrix.Expand.toDoubleMatrix
import org.apache.commons.math3.linear.LUDecomposition
import org.apache.commons.math3.linear.MatrixUtils
import org.junit.Test

internal class DoubleMatrixHelperTest {
    @Test
    fun t1_matrix_add() {
        val matrix1 = makeDoubleMatrix(2, 3)
        matrix1.setMany(
            arrayListOf(
                1, 2, 3, 4, 5, 6,
            ).toDoubleList()
        )
        val matrix2 = makeDoubleMatrix(2, 3)
        matrix1.setMany(
            arrayListOf(
                7, 8, 9, 10, 11, 12,
            ).toDoubleList()
        )
        val result = matrix1 + matrix2
        result.print()
        //8 10 12
        //14 16 18
    }

    @Test
    fun t2_samePositionValueEquals() {
        val matrix1 = makeDoubleMatrix(2, 2)
        matrix1.setMany(
            arrayListOf(
                1, 2, 3, 4,
            ).toDoubleList()
        )

        val matrix2 = makeDoubleMatrix(2, 2)
        matrix2.setMany(
            arrayListOf(
                1, 2, 3, 4,
            ).toDoubleList()
        )

        val matrix3 = makeDoubleMatrix(2, 2)
        matrix3.setMany(
            arrayListOf(
                1, 2, 3, 5,
            ).toDoubleList()
        )

        println(
            matrix1.isSamePositionValueEquals(
                matrix2
            )
        ) // 输出：true
        println(
            matrix1.isSamePositionValueEquals(
                matrix3
            )
        ) // 输出：false
    }

    @Test
    fun t3_matrix_less() {
        val matrix1 = makeDoubleMatrix(2, 2)
        matrix1.setMany(
            arrayListOf(
                1, 2, 3, 4,
            ).toDoubleList()
        )
        val matrix2 = makeDoubleMatrix(2, 2)
        matrix2.setMany(
            arrayListOf(
                1, 2, 3, 3,
            ).toDoubleList()
        )
        val matrix3 = makeDoubleMatrix(2, 2)
        matrix3.setMany(
            arrayListOf(
                1, 2, 3, 5,
            ).toDoubleList()
        )
        matrix1.print()
        matrix2.print()
        println(
            matrix1.isSamePositionValueLessEquals(
                matrix2
            )
        ) // 输出：false
        println(
            matrix1.isSamePositionValueLessEquals(
                matrix3
            )
        ) // 输出：true
    }

    @Test
    fun t4() {
        val matrixData = arrayOf(
            doubleArrayOf(4.0, 3.0), doubleArrayOf(2.0, 1.5) // 这个矩阵是奇异的
        )
        val matrix = MatrixUtils.createRealMatrix(matrixData)

        try {
            val luDecomposition = LUDecomposition(matrix)

            // ... 进一步的操作
            val L = luDecomposition.l
            val U = luDecomposition.u

            println("L 矩阵:")
            for (i in 0 until L.rowDimension) {
                for (j in 0 until L.columnDimension) {
                    print("${L.getEntry(i, j)}\t")
                }
                println()
            }

            println("U 矩阵:")
            for (i in 0 until U.rowDimension) {
                for (j in 0 until U.columnDimension) {
                    print("${U.getEntry(i, j)}\t")
                }
                println()
            }
        } catch (e: Exception) {
            println(e)
            println("矩阵是奇异的，无法进行LU分解。")
        }
    }

    @Test
    fun t5() {
        // 创建一个 2x2 的矩阵
        val matrix1 = DoubleMatrix.makeDoubleMatrix(2, 2)
        matrix1.setMany(listOf(1.0, 2.0, 3.0, 4.0))

        // 创建另一个 2x2 的矩阵
        val matrix2 = DoubleMatrix.makeDoubleMatrix(2)
        matrix2.setMany(listOf(4.0, 3.0, 2.0, 1.0))

        // 打印两个矩阵
        println("Matrix 1:")
        matrix1.print()
        println("Matrix 2:")
        matrix2.print()

        // 执行加法操作
        val sumMatrix = matrix1 + matrix2
        println("Sum:")
        sumMatrix.print()

        // 比较矩阵
        val isEqual = matrix1.isSamePositionValueEquals(matrix2)
        println("Matrix 1 is equal to Matrix 2: $isEqual")

        val isLess = matrix1.isSamePositionValueLess(matrix2)
        println("Matrix 1 is less than Matrix 2: $isLess")
    }

    @Test
    fun t6() {
        val data: DoubleListList = arrayListOf(
            arrayListOf(1.0, 2.0), arrayListOf(3.0, 4.0)
        )

        val matrix = data.toDoubleMatrix()
        matrix.print() // 打印矩阵
    }
}